<?php
//详细使用方法参考 https://github.com/overtrue/wechat/wiki
namespace app\portal\controller;

use cmf\controller\AdminBaseController;
use think\Cache;
use think\Db;
use think\Request;
use Overtrue\Wechat\Media;
use Overtrue\Wechat\Image;
use Overtrue\Wechat\Message;
use Overtrue\Wechat\Broadcast;
use Overtrue\Wechat\User;
use Overtrue\Wechat\Tag;
use Overtrue\Wechat\Cache as OCache;
use app\portal\model\WechatNewsModel;

class AdminWechatController extends AdminbaseController {

    private $up_images;
    private $media;
    private $broadcast;

    public function __construct()
    {
        parent::__construct();
        define('CURLOPT_SAFE_UPLOAD',true);
        header("Content-type:text/html;charset=utf-8");
            
        // $appId  = 'wxc92d977aea3048bb';
        // $secret = '46ad4a50c348ff96b24211c53b777df4';
        // $appId  = 'wx4c7af4779dec227b';
        // $secret = '1e7306a43535177a4864db9853b859dd';
    
		$config = Db::name('wechat_public_number')->where('number_id',1)->find();
		if($config){
			$this->appid = $appId  = $config['appid'];
			$secret = $config['secret'];
		}else{
			$this->error('请设置微信公众号信息',url('AdminWechatPublicNumber/index'));
			exit;
		}
	
        // 写入
        OCache::setter(function($key, $value, $lifetime){
            return cache('Hunuo'.$key, $value, $lifetime);
        });

        // 读取
        OCache::getter(function($key){
            return cache('Hunuo'.$key);
        });
        
        $this->up_images = new Image($appId, $secret);      
        $this->media = new Media($appId, $secret);
        $this->broadcast = new Broadcast($appId, $secret);
		$this->userService = new User($appId, $secret);
		$this->tag = new Tag($appId, $secret);
    }
     
    public function index(){
        $param                = $this->request->param();
        $param['sort_by']     = $this->request->param('sort_by','create_time','trim');
        $param['list_order']  = $this->request->param('list_order','DESC','trim');

        $param['source']      = $this->request->param('source',0,'intval');

        $wechatNewsModel = new WechatNewsModel();
        $data        = $wechatNewsModel->adminList($param);
        
        $data->appends($param);

        //当前排序依据
        $sort_flag  = sort_flag($param);
        $this->assign($sort_flag['tag'], $sort_flag['img']);

        $this->assign('start_time', isset($param['start_time']) ? $param['start_time'] : '');
        $this->assign('end_time', isset($param['end_time']) ? $param['end_time'] : '');
        $this->assign('keyword', isset($param['keyword']) ? $param['keyword'] : '');
        $this->assign('source', $param['source']);
        $this->assign("filter",$param);
        $this->assign('list', $data->items());
        $this->assign('page', $data->render());

        $actions = ['add', 'edit', 'delete', 'send', 'sendTest', 'refresh'];
        $this->assign('actions', actions_check($this->request->module().'/'.$this->request->controller().'/', $actions));

        return $this->fetch();
    }

    /**
     * 待审核文章列表
     * @adminMenu(
     *     'name'   => '待审核内容',
     *     'parent' => 'index',
     *     'display'=> true,
     *     'hasView'=> true,
     *     'order'  => 10000,
     *     'icon'   => '',
     *     'remark' => '待审核文章列表',
     *     'param'  => ''
     * )
     */
    public function checkList()
    {
        $param      = $this->request->param();
        $stepIndex  = $this->request->param('step_index', 1, 'intval');

        $param['sort_by']     = $this->request->param('sort_by','id','trim');
        $param['list_order']  = $this->request->param('list_order','DESC','trim');

        $param['source']      = $this->request->param('source',0,'intval');

        $wechatSetting = cmf_get_option('wechat_setting');

        //角色id
        $role_id  = session('ROLE_ID');
        //该流程下的所有审核步骤
        $stepList = Db::name('audit_flow_step')
                 -> where('audit_id',$wechatSetting['audit_id'])
                 -> order('step_index asc')
                 -> select()
                 -> toArray();

        //提取该管理员角色拥有的该流程下的步骤
        foreach ($stepList as $k => $v) {
            $auth_role_id = explode(',',$v['auth_role_id']);
            //若当前登录的不是超级管理员，判断是否拥有该步骤的权限
            if( $role_id!=1 ){
                if( !in_array($role_id, $auth_role_id) ){
                    continue;
                }
            }
            //将有权限的步骤放到新数组中
            $haveStep[$v['step_index']] = $v['step_name'];
        }

        //若当前选择的步骤序号大于该流程下最大的步骤序号，则重置为1(第一个审核步骤)
        if( !empty($stepList) ){
            $stepCount = count($stepList);
            $lastIndex = $stepList[$stepCount-1]['step_index'];

            if( $stepIndex > $lastIndex ){
                $stepIndex = 1;
            }                
        }

        //待审核文章列表
        if( !empty($haveStep) ){
            $param['audit_status'] = ['=',$stepIndex];
            $wechatNewsModel       = new WechatNewsModel();
            $data                  = $wechatNewsModel->adminList($param);
            
            $data->appends($param);

            $this->assign('list', $data->items());
            $this->assign('page', $data->render());

            $haveStepList = html_options($haveStep, $stepIndex);
            $this->assign('have_step_list', $haveStepList);     //拥有的步骤列表
        }


        $this->assign('start_time', isset($param['start_time']) ? $param['start_time'] : '');
        $this->assign('end_time', isset($param['end_time']) ? $param['end_time'] : '');
        // $this->assign('keyword', isset($param['keyword']) ? $param['keyword'] : '');

        //当前排序依据
        $sort_flag  = sort_flag($param);
        $this->assign($sort_flag['tag'], $sort_flag['img']);

        $this->assign('step_index', $stepIndex);            //当前所在步骤
        $this->assign('category_tree', $categoryTree);      //分类树
        $this->assign('category', $categoryId);             //当前分类id
        $this->assign('source', $param['source']);
        $this->assign("filter",$param);
        return $this->fetch();
    }

    public function edit(){
        $mediaId = $this->request->param('id'); 
        try { 
            $news = $this->media->forever()->download($mediaId);
        } catch (\Exception $e) {       
			$temp = json_decode(Db::name('wechat_news')->where('media_id',$mediaId)->value('content'),true);
            //$this->error($e->getMessage()); 
			$news['news_item'] = $temp;
        }
		//print_r($news);
		if(!$news['news_item']){
			return $this->error('不存在的素材');
		}
		foreach($news['news_item'] as $k=>$v){
			//$news['news_item'][$k]['content'] = htmlspecialchars_decode($v['content'] );
			//$news['news_item'][$k]['content'] = $v['content'] ;
		}
		//print_r($news);
        $this->assign('news',$news);
        return $this->fetch();
    }           
    
    public function add(){
        return $this->fetch();
    }   
        
        
    public function editPost(){
        $param = $this->request->param();

        if(empty($param['thumb_media_id'])){
            if( empty($param['thumb_url']) ){
                $this->error('请上传缩略图！');
            }
        }

        if( empty($param['digest']) ){
            $this->error('请填写摘要！');
        }

        $wechatNewsModel = new WechatNewsModel();

        try { 
            $appid = db('wechat_public_number')->value('appid');

            $uploadPath = config('upload_path');
            if(empty($param['thumb_media_id'])){
                $param['thumb_url']      = cmf_asset_relative_url($param['thumb_url']);
                $path                    = WEB_ROOT . $uploadPath . $param['thumb_url'];
                $image                   = $this->media->forever()->image($path);    
                $param['thumb_media_id'] = $image['media_id'];
                $actionName              = '添加';
            }else{
				if(!empty($param['thumb_url'])){
                    $param['thumb_url']      = cmf_asset_relative_url($param['thumb_url']);
                    $path                    = WEB_ROOT . $uploadPath . $param['thumb_url'];
                    $image                   = $this->media->forever()->image($path);    
                    $param['thumb_media_id'] = $image['media_id'];
				}else{
					$param['thumb_media_id'] = $param['thumb_media_id'];
				}
                $actionName = '编辑';
            }
            
            $article = $param['content'];
			$article = cmf_replace_content_file_url(htmlspecialchars_decode($article), true)	;
            foreach($this->auto_save_image($article) as $v){
                $new_image = $this->up_images->upload($v['filepath']);
                $article = str_replace($v['codepath'],$new_image,$article);
            }          
		
			$article = cmf_replace_content_file_url(htmlspecialchars_decode($article), true)	;
			//print_r($article);die();
            $news = array();
            $news[] = array(
                "title"                 => $param['title'],
                "digest"                => $param['digest'],
                "thumb_media_id"        => $param['thumb_media_id'],
                "thumb_url"             => $param['thumb_url'],
                "author"                => $param['author'],
                "show_cover_pic"        => 0,
                "content"               => $article, //htmlspecialchars(cmf_replace_content_file_url(htmlspecialchars_decode($value), true))
                "content_source_url"    => $param['content_source_url'],
                "need_open_comment"     => $param['need_open_comment'],
                "only_fans_can_comment" => $param['only_fans_can_comment']
            );
            
            if(empty($param['media_id'])){
                $media_id = $this->media->news($news);
                $data = array(
                    'media_id' => $media_id,
                    'title'    => $param['title'],
                    'content'  => json_encode($news),
                    'appid'    => $appid,
                    'user_id'  => cmf_get_current_admin_id(),
                );

                //不需要审核的情况，为超级管理员所添加的或者文章所属分类不需要审核流程
                $wechatSetting = cmf_get_option('wechat_setting');
                $audit_id      = $wechatSetting['audit_id'];
                if( !empty($audit_id) ){
                    $auditStatus = db('audit_flow')->value('status');
                }
                if( session('ROLE_ID') == 1 || empty($audit_id) || empty($auditStatus) ){
                    $data['audit_status'] = 99;
                }


                $wechatNewsModel->allowField(true)->data($data, true)->isUpdate(false)->save();

                $id = $wechatNewsModel->getLastInsID();
                //操作日志
                admin_log('id-'.$id, 'add', '微信图文素材');
            }else{
                $this->media->updateNews($param['media_id'], $news, 0);
				$data = array(
                    'title'       => $param['title'],
                    'content'     => json_encode($news),
                    'update_time' => time(),
                );

                $wechatNewsModel->where('media_id', $param['media_id'])->update($data);

                //操作日志
                $id = $wechatNewsModel->where('media_id', $param['media_id'])->value('id');
                admin_log('id-'.$id, 'edit', '微信图文素材');
            }       			
        } catch (\Exception $e) {       
            $this->error($e->getMessage()); 
        }
        $this->success($actionName.'图文素材成功',url('adminWechat/index'));
    }
    
    public function send(){ 
        $news_media_id = $this->request->param('id');   
        
        //var_dump($broadcast->send($message)->preview($openId));
        try { 
            $message = Message::make('mp_news')->media($news_media_id);
            $this->broadcast->send($message)->to();

            db('wechat_news')->where('media_id', $news_media_id)->update(['status'=>1]);
            // $data = [ 'media_id' => $news_media_id];
            // Db::name('wechat_news')->insert($data);
        } catch (\Exception $e) {       
            $this->error($e->getMessage()); 
        }

        //操作日志
        admin_log('', '', '发送微信文章');

        $this->success('发布成功'); 
    }    
	
    public function sendTest(){ 
        $news_media_id = $this->request->param('id');   
        
        //var_dump($broadcast->send($message)->preview($openId));
        try { 
            $message = Message::make('mp_news')->media($news_media_id);
            //$this->broadcast->send($message)->to();   //推送所有人（慎用）
			// $this->broadcast->send($message)->preview('Yip_-_', Broadcast::PREVIEW_BY_WXH);  //推送某个微信号
			
            //db('wechat_news')->where('media_id', $news_media_id)->update(['status'=>1]);
            // $data = [ 'media_id' => $news_media_id];
            // Db::name('wechat_news')->insert($data);
        } catch (\Exception $e) {       
            $this->error($e->getMessage()); 
        }

        //操作日志
        admin_log('', '', '发送预览微信文章');
        
        $this->success('发布成功'); 
    }
        
    public function delete(){   
        $param = $this->request->param();   

        $wechatNewsModel = new WechatNewsModel();

        try {
            if (isset($param['id'])) {
                $id     = $this->request->param('id', 0, 'intval');
                $result = $wechatNewsModel->where(['id' => $id])->find();

                //彻底删除
                if( $this->media->delete($result['media_id']) ){
                    $wechatNewsModel->where(['id' => $id])->delete();
                }

                //加入回收站
                // $data = [
                //     'object_id'   => $result['id'],
                //     'create_time' => time(),
                //     'table_name'  => 'wechat_news',
                //     'name'        => $result['title']
                // ];

                // $resultPortal = $wechatNewsModel
                //              -> where(['id' => $id])
                //              -> update(['delete_time' => time()]);

                // if ($resultPortal) {
                //     Db::name('recycleBin')->insert($data);
                // }
            }

            if (isset($param['ids'])) {
                $ids     = $this->request->param('ids/a');
                $recycle = $wechatNewsModel->where(['id' => ['in', $ids]])->select();

                //彻底删除
                foreach ($recycle as $k => $v) {
                    $this->media->delete($v['media_id']);   //删除微信服务器端数据
                }

                $wechatNewsModel->where(['id' => ['in', $ids]])->delete();

                //加入回收站
                // $result  = $wechatNewsModel->where(['id' => ['in', $ids]])->update(['delete_time' => time()]);
                // if ($result) {
                //     foreach ($recycle as $value) {
                //         $data = [
                //             'object_id'   => $value['id'],
                //             'create_time' => time(),
                //             'table_name'  => 'portal_post',
                //             'name'        => $value['post_title']
                //         ];
                //         Db::name('recycleBin')->insert($data);
                //     }
                //     $this->success("删除成功！", '');
                // }
            }

            // if($this->media->delete($news_media_id)){
            //     Db::name('wechat_news')->where('media_id', $news_media_id)->delete();
            //     $this->success('删除成功'); 
            // }else{
            //     $this->error('删除失败');   
            // }
            
        } catch (\Exception $e) {       
            // $this->error($e->getMessage()); 
            $this->error('删除失败','');   
        }

        $this->success('删除成功','');
    }
	
    //通过审核
    public function pass(){
        $stepIndex  = $this->request->param('step_index', 1, 'intval');

        $wechatSetting = cmf_get_option('wechat_setting');

        //该流程下的所有审核步骤
        $maxStepIndex = Db::name('audit_flow_step')
                     -> where('audit_id',$wechatSetting['audit_id'])
                     -> max('step_index');

        if( $maxStepIndex>$stepIndex ){
            $status = $stepIndex+1;
        } else {
            $status = 99;
        }
        
        parent::passStep(Db::name('wechat_news'), $status ,'audit_status');
        $this->success("审核成功！",'');
    }

	public function refresh(){
		$mediaIds = db('wechat_news')->column('media_id');
        $appid    = db('wechat_public_number')->value('appid');
		
		try{
			$count = $this->media->stats('news');
			$p = ceil($count/20);  
			$offset = 0;
			$news = array();
			for($i=1;$i<=$p;$i++){			
				$news_temp = $this->media->lists('news', $offset, 20);
				foreach($news_temp['item'] as $v){
					if(!in_array($v['media_id'],$mediaIds)){
						$data = array(
                            'media_id'    => $v['media_id'],
                            'title'       => current($v['content']['news_item'])['title'],
                            'content'     => json_encode($v['content']['news_item']),
                            'create_time' => $v['content']['create_time'],
                            'update_time' => $v['content']['update_time'],
                            'appid'       => $appid,
                        );
						Db::name('wechat_news')->insert($data);
					}
				}		
				$offset +=19;
			}
        } catch (\Exception $e) {       
            $this->error($e->getMessage()); 
        }
        
		$this->success('刷新成功');
	}

    /*
     *@param $body 一段html文本
     *@param $filepath 保存文件的路径,默认为当前站点根目录中的uploads文件夹
     *返回值是一个已经下载的图片信息的数组
     */
    public function auto_save_image($body, $filepath = '/upload/wechat') {
        //set_time_limit(1800);
        //echo $body;
        $img_array = array();
        $body      = htmlspecialchars_decode($body);
        //preg_match_all('/(src)=[\"|\'| ]{0,1}([^>]+\.(gif|jpg|jpeg|bmp|png))[\"|\'| ]{0,1}/i', $body, $img_array);
        preg_match_all('/(http[^>]+\.(gif|jpg|jpeg|bmp|png))[\"|\'| ]{0,1}/i', $body, $img_array);
        $img_array = array_unique($img_array[1]);
        $imginfo   = array();
        foreach ($img_array as $key => $value) {
            $imginfo[] = $this->downloadImage( $value, $filepath);
        }
        return $imginfo;
    }
    public function createFolder($path) {
        if (!file_exists($path)) {
            $this->createFolder(dirname($path));
            mkdir($path, 0700);
        }
    }
    /**
     * 下载远程图片
     * @param string $url 图片的绝对url
     * @param string $filepath 文件的完整路径（包括目录，不包括后缀名,例如/www/images/test） ，此函数会自动根据图片url和http头信息确定图片的后缀名
     * @return mixed 下载成功返回一个描述图片信息的数组，下载失败则返回false
     */
    public function downloadImage($url, $filepath) {
        $Yurl         = $url;
        $milliSecond  = date('YmdHms') . strftime("%H%M%S", time()).rand(); //文件名
        $Savefilepath = $filepath . "/image/" . date("Ym"); //文件保存路径
        $filepath     = str_replace("\\", '/', $_SERVER['DOCUMENT_ROOT'] . $Savefilepath); //转化为当前网站目录
        if (!file_exists($filepath)) {
            $this->createFolder($filepath);
        }
    //如果文件夹不存在就创建
        $filepath = $filepath . "/" . $milliSecond; //加上文件名
        if (strtolower(substr($url, 0, 4)) != 'http') {
            if (substr($url, 0, 1) == '/') {
                $url = substr($url, 1);
            }
            $url = $url;
        } else {
            $url = $url;
        }
        //服务器返回的头信息
        $responseHeaders = array();
        //原始图片名
        $originalfilename = '';
        //图片的后缀名
        $ext = '';
        $ch  = curl_init($url);
        //设置curl_exec返回的值包含Http头
        curl_setopt($ch, CURLOPT_HEADER, 1);
        //设置curl_exec返回的值包含Http内容
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        //设置抓取跳转（http 301，302）后的页面
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
        //设置最多的HTTP重定向的数量
        curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
        //服务器返回的数据（包括http头信息和内容）
        $html = curl_exec($ch);
        //获取此次抓取的相关信息
        $httpinfo = curl_getinfo($ch);
        curl_close($ch);
        if ($html !== false) {
            //分离response的header和body，由于服务器可能使用了302跳转，所以此处需要将字符串分离为 2+跳转次数 个子串
            $httpArr = explode("\r\n\r\n", $html, 2 + $httpinfo['redirect_count']);
            //倒数第二段是服务器最后一次response的http头
            $header = $httpArr[count($httpArr) - 2];
            //倒数第一段是服务器最后一次response的内容
            $body = $httpArr[count($httpArr) - 1];
            $header .= "\r\n";
            //获取最后一次response的header信息
            preg_match_all('/([a-z0-9-_]+):\s*([^\r\n]+)\r\n/i', $header, $matches);
            if (!empty($matches) && count($matches) == 3 && !empty($matches[1]) && !empty($matches[1])) {
                for ($i = 0; $i < count($matches[1]); $i++) {
                    if (array_key_exists($i, $matches[2])) {
                        $responseHeaders[$matches[1][$i]] = $matches[2][$i];
                    }
                }
            }
            //获取图片后缀名
            if (0 < preg_match('{(?:[^\/\\\\]+)\.(jpg|jpeg|gif|png|bmp)$}i', $url, $matches)) {
                $originalfilename = $matches[0];
                $ext              = $matches[1];
            } else {
                if (array_key_exists('Content-Type', $responseHeaders)) {
                    if (0 < preg_match('{image/(\w+)}i', $responseHeaders['Content-Type'], $extmatches)) {
                        $ext = $extmatches[1];
                    }
                }
            }
            //保存文件
            if (!empty($ext)) {
                $filepath .= ".$ext";
                //如果目录不存在，则先要创建目录
                $this->createFolder(dirname($filepath));
                $local_file = fopen($filepath, 'w');
                if (false !== $local_file) {
                    if (false !== fwrite($local_file, $body)) {
                        fclose($local_file);
                        $sizeinfo = getimagesize($filepath);
                        return array(
                            'width'        => $sizeinfo[0],
                            'height'       => $sizeinfo[1],
                            'codepath'     => $Yurl, //源代码中文件的路径
                            'jueduipath'   => $url, //文件绝对路径
                            'savefilepath' => str_replace(str_replace('\\', '/', $_SERVER['DOCUMENT_ROOT']), '', $filepath), //文件保存的相对路径
                            'filepath'     => $filepath,
                            'oldfilename'  => $originalfilename,
                            'newfilename'  => pathinfo($filepath, PATHINFO_BASENAME),
                        );
                    }
                }
            }
        }
        return false;
    }
    
    //相对转绝对
    public function relative_to_absolute($content, $feed_url) {
        preg_match('/(http|https|ftp):\/\//', $feed_url, $protocol);
        $server_url = preg_replace("/(http|https|ftp|news):\/\//", "", $feed_url);
        $server_url = preg_replace("/\/.*/", "", $server_url);

        if ($server_url == '') {
            return $content;
        }

        if (isset($protocol[0])) {
            $new_content = preg_replace('/href="\//', 'href="'.$protocol[0].$server_url.'/', $content);
            $new_content = preg_replace('/src="\//', 'src="'.$protocol[0].$server_url.'/', $new_content);
        } else {
            $new_content = $content;
        }
        return $new_content;
    }
	
	public function get_user(){
		//$userService = new User($appId, $secret);
		//$user = $this->userService->lists();
		//$tag = $this->tag->lists();
		$user = $this->tag->usersOfTag(108);
		print_r("<pre>");
		print_r($user);
	}
	
	public function music(){
		//$voice = $this->media->forever()->voice(ROOT_PATH . 'upload' . DS . 'wechat'. DS .'C100000cWYGc3SDZrY.mp3');  
		$voice = 'TRGzqD9kWYnDkYwOriZDRzdXvpCmnaRfw4b0ck00nsY';  
		var_dump($this->media->forever()->download($voice));
		/* $file = request()->file('music');
		if($file){
			$info = $file->move(ROOT_PATH . 'public' . DS . 'uploads');
			if($info){
				// 成功上传后 获取上传信息
				// 输出 jpg
				echo $info->getExtension();
				// 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
				echo $info->getSaveName();
				// 输出 42a79759f284b767dfcb2a0197904287.jpg
				echo $info->getFilename(); 
			}else{
				$this->success($file->getError());
			}
		} */
	}
	
}

